package com.cositas.dulces.lp.fb;

import java.io.Serializable;
import java.util.regex.Pattern;

import org.apache.commons.codec.binary.Base64;

import com.cositas.dulces.lp.FacebookAppData;
import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.KeyFactory;
import com.google.appengine.repackaged.org.json.JSONException;
import com.google.appengine.repackaged.org.json.JSONObject;
import com.restfb.types.User;

/**
 *
 * @author Eric Jacob
 */
public class SignedRequest implements Serializable {

    /**
	 * 
	 */
	private static final long serialVersionUID = 8525995498192307345L;
	private String encodedSig;
    private String encodedData;
    private String signed_request;
    private String urlDecodedEncodedData;
    private User facebookUser;
    private Key participantKey;
    
    private boolean storedCompletedInSession = false;
    
    private transient JSONObject data;
    private transient Base64 base64;
    
    private String vote;
    
    private static final String quoted = Pattern.quote(".");

    public SignedRequest(String value) throws JSONException {
        String[] splits = value.split(quoted);
        encodedSig = splits[0];
        signed_request = value;
        encodedData = splits[1];
        urlDecodedEncodedData = base64UrlDecode(encodedData);
    }
    
    public void setAppData(String appData) {
    	try {
			this.getData().put("app_data", appData);
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
    }
    
    public String getAppData() {
    	try {
    		if (this.getData().has("app_data")) {
    			return this.getData().getString("app_data");
    		} else {
    			return null;
    		}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			return null;
		}
    }
    
    public void clearAppData() {
    	this.getData().remove("app_data");
    }

    public boolean verify(String secret) throws JSONException {
//        boolean sigVerified = false;
//        String algorithm = data.getString("algorithm");
//        if ("HMAC-SHA256".equals(algorithm)) {
//            try {
//                SecretKeySpec key = new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256");
//                Mac hmac = Mac.getInstance("HmacSHA256");
//                hmac.init(key);
//                String expectedSig = new String(hmac.doFinal(encodedData.getBytes("UTF-8")));
//                if (expectedSig.equals(sig)) {
//                    sigVerified = true;
//                }
//            } catch (Exception ex) {
//            }
//        }
//        return sigVerified;
    	return true;
    }
    
    public boolean isFan() {
    	try {
    		if (FacebookAppData.isDev()) {
    			//return this.getData().getJSONObject("page").getBoolean("liked");
    			return true;
    		}
			return this.getData().getJSONObject("page").getBoolean("liked");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		}
    }
    
    public boolean hasOAuth() {
    	try {
    		if (this.getData().has("oauth_token")) {
    			return this.getData().getString("oauth_token") != null;
    		} else {
    			return false;
    		}
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			//e.printStackTrace();
			return false;
		}
    }
    
    public String getOAuth() {
    	try {
			return this.getData().getString("oauth_token");
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
    }
    
    public String getSignedRequest() {
        return signed_request;
    }

    public JSONObject getData() {
        try {
        	if (data == null) {
        		data = (JSONObject) new JSONObject(urlDecodedEncodedData);
        	}
			return data;
		} catch (JSONException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		}
    }

    private String base64UrlDecode(String encoded) {
        return new String(getBase64().decode(encoded));
    }

	private Base64 getBase64() {
		if (base64 == null) {
			base64 = new Base64(true);
		}
		return base64;
	}

	public User getFacebookUser() {
		if (facebookUser == null) {
			facebookUser = FacebookUtils.me(this.getOAuth());
		}
		return facebookUser;
	}

	public void setFacebookUser(User facebookUser) {
		this.facebookUser = facebookUser;
	}

	public void setParticipantKey(Key participantKey) {
		this.participantKey = participantKey;
	}

	public boolean isStoredCompletedInSession() {
		return storedCompletedInSession;
	}

	public void setStoredCompletedInSession(boolean storedCompletedInSession) {
		this.storedCompletedInSession = storedCompletedInSession;
	}

	public void setVote(String vote) {
		this.vote = vote;
	}
}